﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using CTThrottling;
using CTThrottling.Common;
using StackExchange.Redis;

namespace Throttling
{
    class Program
    {
        static void Main(string[] args)
        {            

        }

        /// <summary>
        /// 限流（令牌桶模式+漏桶模式）
        /// </summary>
        public void Limiting()
        {
            var service = LimitingFactory.Build(LimitingType.TokenBucket, 500, 5);

            while (true)
            {
                var result = service.Request();
                //如果返回true，说明可以进行业务处理，否则需要继续等待
                if (result)
                {
                    //业务处理......
                    Console.WriteLine($"业务处理......;时间:{DateTime.Now.Ticks}");
                }
                else
                {
                    //业务处理......
                    Console.WriteLine($"等待......;时间:{DateTime.Now.Ticks}");
                    Thread.Sleep(5000);
                }

            }

        }

        /// <summary>
        /// Redis分布式锁--商品秒杀
        /// </summary>
        public void RedisLock()
        {
            Console.WriteLine("Start..........");
            RedisStackExchangeHelper _redis = new RedisStackExchangeHelper();
            var db = _redis.GetDatabase();
            RedisValue token = Environment.MachineName;
            //实际项目秒杀此处可换成商品ID
            if (db.LockTake("test", token, TimeSpan.FromSeconds(10)))
            {
                try
                {
                    Console.WriteLine("Working..........");
                    Thread.Sleep(5000);
                }
                finally
                {
                    db.LockRelease("test", token);
                }
            }

            Console.WriteLine("Over..........");
        }

        /// <summary>
        /// Ip单位时间访问次数限制
        /// </summary>
        public void RedisLimitIp()
        {
            RedisStackExchangeHelper _redis = new RedisStackExchangeHelper();
            var db = _redis.GetDatabase();
            var times = db.StringIncrement("IP");
            if (1 == times)
            {
                db.KeyExpire("IP", TimeSpan.FromSeconds(60));
            }
            if (times > 3)
            {
                Console.WriteLine("do other thing..........");
                var liveTime = db.KeyTimeToLive("IP");
                if (liveTime == null)
                {
                    db.KeyExpire("IP", TimeSpan.FromSeconds(60));
                }
            }
        }

    }

}
